package com.wmh.baseservice.common.shiro.realm;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wmh.baseservice.admin.entity.AdInfo;
import com.wmh.baseservice.admin.service.AdInfoService;
import com.wmh.baseservice.admin.service.AdRoleService;
import com.wmh.baseservice.common.ex.ServiceException;
import com.wmh.baseservice.common.redis.utils.RedisUtil;
import com.wmh.baseservice.common.shiro.bean.JwtToken;
import com.wmh.baseservice.common.shiro.config.ShiroConfig;
import com.wmh.baseservice.common.shiro.jwt.JwtTokenUtil;
import com.wmh.baseservice.common.utils.CommUtil;
import com.wmh.baseservice.common.utils.web.UserUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;


/**
 * @author xy
 * @Date: 2021-10-29 16:10
 * @describe JWT身份权限校验
 */
public class JwtRealm extends AuthorizingRealm {

    @Resource
    private AdInfoService adInfoService;
    @Resource
    private AdRoleService adRoleService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private UserUtil userUtil;

    @Resource
    private HttpServletRequest request;


    /*
     * 标识这个Realm是专门用来验证JwtToken
     * 不负责验证其他的token（UsernamePasswordToken）
     * */
    @Override
    public boolean supports(AuthenticationToken token) {
        //这个token就是从过滤器中传入的jwtToken
        return token instanceof JwtToken;
    }

    //权限
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String userName = SecurityUtils.getSubject().getPrincipal().toString();
        //获得该用户角色
        if (userName.contains(ShiroConfig.SHIRO_ADMIN)) {
            Long adId = userUtil.getId();
            return adInfoService.getSimpleAuthorizationInfo(adId);
        } else {
            throw new UnauthorizedException();
        }
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String jwt = (String) token.getPrincipal();
        if (!CommUtil.checkNull(jwt)) {
            throw new ServiceException("jwtToken 不允许为空");
        }
        if (!JwtTokenUtil.isTokenExpired(jwt)) {
            throw new UnauthenticatedException();
        }
        //验证user是否存在
        String users = JwtTokenUtil.getUsernameFromToken(jwt).get("account").toString();
        String[] usersSplit = users.split("\\.");
        if (usersSplit.length != 2) {
            throw new UnauthenticatedException();
        }
        String username = usersSplit[0];
        String password;

        if (username.contains(ShiroConfig.SHIRO_ADMIN)) {
            //管理员
            AdInfo adInfo = adInfoService.getOneForUpdate(new QueryWrapper<AdInfo>().eq(AdInfo.ACCOUNT, username.replace(ShiroConfig.SHIRO_ADMIN, "")));
            if (!CommUtil.checkNull(adInfo)) {
                throw new ServiceException("账号不存在");
            }
            password = adInfo.getPassword();
            userUtil.set(adInfo);
        } else {
            throw new ServiceException("身份错误");
        }
        return new SimpleAuthenticationInfo(users, password, JwtRealm.class.getName());
    }
}
